﻿#define _CRT_SECURE_NO_WARNINGS
#pragma execution_character_set("utf-8")

#include <stdio.h>
#include "function.h"
#include "enclosure.h"
#include "struct.h"

void Login() { // 登录账户

    if (strcmp(User, "null") != 0) { printf("请先退出\n"); return; }

    account* tmp = pH_account->next;

    while (tmp != NULL) {

        if (strcmp(tmp->user, ref[0]) == 0 && strcmp(tmp->password, ref[1]) == 0) {

            strcpy(User, tmp->user);

            View_Level = tmp->view_level;

            printf("登录成功\n");

            return;

        }

        tmp = tmp->next;

    }

    printf("登录失败\n");

    return;

}

void Exit() { // 退出账户

    strcpy(User, "null");

    View_Level = -1;

    printf("您已经退出账户 \n");

}

void Create() { // 新建账户

    if (View_Level < 3) { printf("账户权限不足 \n"); return; }

    int num = Check_int(ref[2], strlen(ref[2]), 1, 3);

    if (num == -1) { printf("没有对应的权限等级 \n"); return; }

    if(Check_space(ref[0])==1){ printf("用户名不能带有空格 \n"); return; }

    if (strlen(ref[0]) > 18 || strcmp(ref[0], "") == 0) { printf("用户名格式不正确 \n"); return; }

    if (strlen(ref[1]) > 16 || strlen(ref[1]) < 8) { printf("密码格式不正确 \n"); return; }

    for (int i = 0; i < strlen(ref[1]); i++) {

        if (!((ref[1][i] >= '0' && ref[1][i] <= '9') || (ref[1][i] >= 'a' && ref[1][i] <= 'z') || (ref[1][i] >= 'A' && ref[1][i] <= 'Z'))) { printf("密码格式不正确，请仅用大小写英文和数字构成 \n"); return; }

    } // 判断参数合法性

    int check = 0;

    account* pcheck=pH_account->next;

    while (pcheck != NULL) {

        if (strcmp(pcheck->user, ref[0]) == 0) {

            printf("账户已存在\n");

                check = 1;

        }

        pcheck = pcheck->next;

    }
    
    if (check == 1) return;

    create_account();

    account* tmp = pT_account;

    strcpy(tmp->user, ref[0]);

    strcpy(tmp->password, ref[1]);

    tmp->view_level = num;

    printf("创建账户成功\n");

    return;

}

void Reset() { // 改密码 

    if (View_Level < 3 && strcmp(User, ref[0]) != 0) { printf("账户权限不足\n"); return; }

    if (strlen(ref[2]) > 16 || strlen(ref[2]) < 8) { printf("密码长度不正确\n"); return; }

    for (int i = 0; i < strlen(ref[2]); i++) {

        if (!((ref[2][i] >= '0' && ref[2][i] <= '9') || !(ref[2][i] >= 'a' && ref[2][i] <= 'z') || !(ref[2][i] >= 'A' && ref[2][i] <= 'Z'))) { printf("密码格式不正确，请仅用大小写英文和数字构成 \n "); return; }

    }

    account* tmp = pH_account->next;

    while (tmp != NULL) {

        if (strcmp(tmp->user, ref[0]) == 0) {

            if (strcmp(tmp->password, ref[1]) == 0) {

                strcpy(tmp->password, ref[2]);

                printf("密码修改成功\n");

            }

            else { printf("原密码不正确\n"); }

            return; 

        }

        tmp = tmp->next;

    }

    printf("账户未找到\n");

    return;

}


void Change() { // 修改账户阅览等级

    if (View_Level < 3 ) { printf("账户权限不足 \n"); return; }

    int num = Check_int(ref[1], strlen(ref[1]), 1, 3);

    if (num == -1) { printf("没有对应的权限等级\n"); return; }  // 判断参数合法性

    account* tmp = pH_account->next;

    while (tmp != NULL) {

        if (strcmp((tmp)->user, ref[0]) == 0) {

            tmp->view_level = num;

            printf("更改阅览等级成功\n");

            return;

        }

        tmp = tmp->next;

    }

    printf("不存在该账户\n");

    return;

}

void Remove() { // 删除账户

    if (View_Level < 3) { printf("账户权限不足 \n"); return; }

    account* tmp = pH_account;

    while (tmp->next != NULL) {

        if (strcmp((tmp->next)->user, ref[0]) == 0) {

            delete_account(tmp);

            if (strcmp(User, ref[0]) == 0) Exit();

            printf("账户删除成功\n");

            return;

        }

        tmp = tmp->next;

    }

    printf("不存在该账户\n");

    return;

}

void Delete() { // 删除信息

    if (View_Level < 3) { printf("账户权限不足 \n"); return; }

    int type = Check_int(ref[0], strlen(ref[0]), 1, 5);

    student* p_tmp = (pH_student)->next;

    while (p_tmp->next != NULL) { // 这是因为我们要删除的是“下一位的节点”

        if (strcmp((p_tmp->next)->id, ref[1]) == 0) break;

        p_tmp = p_tmp->next;

    }


    if (p_tmp->next == NULL) { printf("未找到相关学生，请检查学号等信息是否正确\n"); return; }

    if (type == 1) {

        delete_student(p_tmp);

        printf("成功删除学生 \n");

        return;

    }

    if (type == 2) {

        read_subject(p_tmp->next);

        subject* p = (p_tmp->next)->pH_subject;

        while (p->next != NULL) {

            if (strcmp((p->next)->node, ref[2]) == 0) {

                delete_subject(p);

                printf("成功删除学科 \n");

                write_subject(p_tmp->next);

                return;

            }

            p = p->next;

        }

        printf("未找到该学生的学科\n");

        write_subject(p_tmp->next);

    }

    if (type == 3) {

        read_project(p_tmp->next);

        project* p = (p_tmp->next)->pH_project;

        while (p->next != NULL) {

            if (strcmp((p->next)->node, ref[2]) == 0) {

                delete_project(p);

                printf("成功删除项目\n");

                write_project(p_tmp->next);

                return;

            }

            p = p->next;

        }

        printf("未找到该学生的项目\n");

        write_project(p_tmp->next);

    }

    if (type == 4) {

        read_medal(p_tmp->next);

        medal* p = (p_tmp->next)->pH_medal;

        while (p->next != NULL) {

            if (strcmp((p->next)->node, ref[2]) == 0) {

                delete_medal(p);

                printf("成功删除竞赛\n");

                write_medal(p_tmp->next);

                return;

            }

            p = p->next;

        }

        printf("未找到该学生的竞赛\n");

        write_medal(p_tmp->next);

    }

    if (type == 5) {

        read_paper(p_tmp->next);

        paper* p = (p_tmp->next)->pH_paper;

        while (p->next != NULL) {

            if (strcmp((p->next)->node, ref[2]) == 0) {

                delete_paper(p);

                printf("成功删除论文\n");

                write_paper(p_tmp->next);

                return;

            }

            p = p->next;

        }

        printf("未找到该学生的论文\n");

        write_paper(p_tmp->next);

    }

    return;

}

void Find() { //查询信息

    if (View_Level < 2 && strcmp(User, ref[1]) != 0) { printf("账户权限不足 \n"); return; }

    int sec = Check_int(ref[0], strlen(ref[0]), 1, 5);

    subject* les = NULL; project* pro = NULL; paper* pap = NULL; medal* med = NULL;

    student* p_find = pH_student->next;

    if (strcmp(ref[1], "") != 0) { //学号不为空

        while (p_find != NULL) { if (strcmp(p_find->id, ref[1]) == 0) break; p_find = p_find->next; }//这个循环结束时，p_find指向查找的学生或空

        if (p_find == NULL) { printf("没有找到该学生\n");  return; }  //找不到学生，立刻返回

        if (sec == 1) {

            printf("姓名：%s \n性别：%s \n学院：%d \n届数：%d \n", (p_find->name), (p_find->sexual), (p_find->major), (p_find->session));

            return;

        } // 查询学生的话直接输出并返回

        read_subject(p_find); read_project(p_find); read_paper(p_find); read_medal(p_find); // 只有查询没有更改，后面不用write了

        les = (p_find->pH_subject)->next; pro = (p_find->pH_project)->next; pap = (p_find->pH_paper)->next; med = (p_find->pH_medal)->next;

        while (les != NULL) { if (strcmp(les->node, ref[2]) == 0) break; else les = les->next; }

        while (pro != NULL) { if (strcmp(pro->node, ref[2]) == 0) break; else pro = pro->next; }

        while (pap != NULL) { if (strcmp(pap->node, ref[2]) == 0) break; else pap = pap->next; }

        while (med != NULL) { if (strcmp(med->node, ref[2]) == 0) break; else med = med->next; }

    }

    if (strcmp(ref[1], "") == 0) { //如果学生参数不存在就进行全局搜索，用test记录结果

        int test = 0;

        student* p_all = pH_student->next; // 用这个指针来遍历所有学生

        while (p_all != NULL) {

            read_subject(p_all); read_project(p_all); read_paper(p_all); read_medal(p_all); // 只有查询没有更改，后面不用write了

            if (sec == 2) {

                les = (p_all->pH_subject)->next;

                while (les != NULL) { if (strcmp(les->node, ref[2]) == 0) { test = 1; break; }  les = les->next; }

                if (test == 1) break;

                else les = NULL;

            }

            if (sec == 3) {

                pro = (p_all->pH_project)->next;

                while (pro != NULL) { if (strcmp(pro->node, ref[2]) == 0) { test = 1; break; }  pro = pro->next; }

                if (test == 1) break;

                else pro = NULL;

            }

            if (sec == 4) {

                pap = (p_all->pH_paper)->next;

                while (pap != NULL) { if (strcmp(pap->node, ref[2]) == 0) { test = 1; break; }  pap = pap->next; }

                if (test == 1) break;

                else pap = NULL;

            }

            if (sec == 5) {

                med = (p_all->pH_medal)->next;

                while (med != NULL) { if (strcmp(med->node, ref[2]) == 0) { test = 1; break; } med = med->next; }

                if (test == 1) break;

                else med = NULL;

            }

            p_all = p_all->next;

        }

    }

    // 最终输出

    if (sec == 2 && (les != NULL)) {

        if (strcmp(ref[1], "") == 0) {

            printf("不能以此种方式查找成绩\n");

            return;

        }

        print_subject(les);

        return;

    }

    if (sec == 3 && (pro != NULL)) {

        print_project(pro);

        return;

    }

    if (sec == 4 && (pap != NULL)) {

        print_paper(pap);
        
        return;

    }

    if (sec == 5 && (med != NULL)) {

        print_medal(med);

        return;

    }

    printf("未找到相关信息\n");

    return;

}

void Manual() { //当用户调用某些函数的时候，输出对应的参数提示

    if (strcmp(Opera, "Change") == 0) {

        printf("参数1 表示用户名 参数2 表示更改后的阅览等级\n");

    }

    if (strcmp(Opera, "Create") == 0) {

        printf("参数1 表示用户名 参数2 表示密码（8—16位数字、字母或特殊字符） 参数3 表示阅览等级\n");

    }

    if (strcmp(Opera, "Delete") == 0) {

        printf("参数1 表示删除数据的类型: 1表示学生 2表示成绩 3表示项目 4表示竞赛 5表示论文\n");

        printf("参数2 表示学生的学号\n");

        printf("参数3 如果删除的数据不是学生, 参数 3 表示删除数据对应的编号\n");

        return;

    }

    if (strcmp(Opera, "Entry") == 0) {

        printf("参数1 表示录入的信息种类（输入 0 为学生 输入 1 为学科 输入 2 为项目 输入 3 为论文 输入 4 为竞赛） 参数2 为学号\n");

        printf("若参数1为 0 :参数3 为姓名 参数4 为性别     参数5 为专业号 参数6 为届数\n");

        printf("若参数1为 1 :参数3 为编号 参数4 为学科名称 参数5 为学分   参数6 为成绩   参数7 为学科类型\n");

        printf("若参数1为 2 :参数3 为编号 参数4 为项目名称 参数5 为成员   参数6 为导师   参数7 为开始日期  参数8 为截止日期   参数9 为分数加成\n");

        printf("若参数1为 3 :参数3 为编号 参数4 为论文名称 参数5 为成员   参数6 为日期   参数7 为分数加成\n");

        printf("若参数1为 4 :参数3 为编号 参数4 为竞赛名称 参数5 为成员   参数6 为主办方 参数7 为日期      参数8 为分数加成\n");

    }

    if (strcmp(Opera, "Exit") == 0) { printf("无参数 \n"); }

    if (strcmp(Opera, "Find") == 0) {

        printf("参数1 表示查询的数据类型：1是学生 2学科 3是项目 4是论文 5是竞赛\n");

        printf("参数2 表示学生的学号(不输入的话就是对所有学生搜索)\n");

        printf("参数3 如果说查询的不是学生，参数3 表示对应编号\n");

    }

    if (strcmp(Opera, "Get") == 0) {

        printf("参数1 表示要查询的学生的学号\n");

        printf("参数2 表示要查询的信息类型 1 表示成绩 2 表示项目 3 表示论文 4 表示竞赛\n");

    }

    if (strcmp(Opera, "Login") == 0) {

        printf("参数1 表示用户名 / 参数2 表示密码 \n");

    }

    if (strcmp(Opera, "Quit") == 0) { printf("无参数 \n"); }

    if (strcmp(Opera, "Rank") == 0) {

        printf("参数1 表示限制学生专业  参数2 表示限制学生届数  参数3 表示显示排名前 n 的学生 \n");

        printf("参数4 是否自定义学科列表（yes/no） / 参数5 表示是否考虑限选（yes/no） / 参数6 表示是否考虑公选（yes/no） /参数7 表示是否考虑加分（yes/no）\n");

        return;

    }

    if (strcmp(Opera, "Remove") == 0) {

        printf("参数1 表示用户名 \n");

    }

    if (strcmp(Opera, "Reset") == 0) {

        printf("参数1 表示用户名 参数2 表示原密码 参数3 表示新密码 \n");

    }

    if (strcmp(Opera, "Revise") == 0) {

        printf("参数1 表示录入的信息种类（输入0 为学生 输入1 为学科 输入2 为项目 输入3 为论文 输入4 为竞赛） 参数2 为学号\n");

        printf("若参数1 为 0 : 参数3 为姓名 参数 4 为性别     参数5 为专业编号 参数6 为届数 \n");

        printf("若参数1 为 1 : 参数3 为编号 参数 4 为学科名称 参数5 为学分     参数6 为成绩   参数7 为学科类型 \n");

        printf("若参数1 为 2 : 参数3 为编号 参数 4 为项目名称 参数5 为参与成员 参数6 为导师   参数7 为开始日期  参数8 为截止日期 参数9 为分数加成 \n");

        printf("若参数1 为 3 : 参数3 为编号 参数 4 为论文名称 参数5 为参与成员 参数6 为日期   参数7 为分数加成 \n");

        printf("若参数1 为 4 : 参数3 为编号 参数 4 为竞赛名称 参数5 为参与成员 参数6 为主办方 参数7 为日期      参数8 为分数加成 \n");

    }

    if (strcmp(Opera, "Save") == 0) { printf("无参数 \n"); }

}

void List() { //列出上述所有用户可以调用的功能函数

    printf("   Login : 登录账户     Exit  : 退出账户\n");

    printf("   Save  : 保存当前修改 Quit  : 结束程序 \n");

    printf("   Find  : 查询信息     Get   : 查询信息      Rank  : 获取排名  \n");

    printf("   Entry : 录入信息     Revise: 修改信息      Delete: 删除信息 \n");

    printf("   Change: 变更账户权限 Create: 创建新的账户  Remove: 删除账户    Reset: 修改当前账户的密码 \n");


    printf("注意: 区分大小写! \n");

}

void Function_call() { // 中转函数，主函数调用这个函数，这个函数再去调用功能函数

    if (strcmp(Opera, "Change") == 0) { Change(); return; }

    if (strcmp(Opera, "Create") == 0) { Create(); return; }

    if (strcmp(Opera, "Delete") == 0) { Delete(); return; }

    if (strcmp(Opera, "Entry") == 0) { Entry(); return; }

    if (strcmp(Opera, "Exit") == 0) { Exit(); return; }

    if (strcmp(Opera, "Find") == 0) { Find(); return; }

    if (strcmp(Opera, "Get") == 0) { Get(); return; }

    if (strcmp(Opera, "Login") == 0) { Login(); return; }

    if (strcmp(Opera, "Quit") == 0) { Quit(); return; }

    if (strcmp(Opera, "Rank") == 0) { Rank(); return; }

    if (strcmp(Opera, "Remove") == 0) { Remove(); return; }

    if (strcmp(Opera, "Reset") == 0) { Reset(); return; }

    if (strcmp(Opera, "Revise") == 0) { Revise(); return; }

    if (strcmp(Opera, "Save") == 0) { Save(); return; }

    printf("未找到该指令，请参考用户手册 \n");

}

void Save() { //保存当前修改 任何人可以执行

    write_student();

    write_account();

    read_student();

    read_account();

    printf("保存成功\n");

    return;

}

void Quit() {

    write_student();

    write_account();

    Loop = 0;

    return;

}

/*rank manual*/

void Rank() { //排名

    if (View_Level < 2) { printf("账户权限不足 \n"); return; }

    int m = Check_int(ref[0], strlen(ref[0]), 0, 99); // m 表示限制专业

    int y = Check_int(ref[1], strlen(ref[1]), 0, 99); // y 表示限制届数 

    int n = Check_int(ref[2], strlen(ref[2]), 0, 999999); // n 表示需要输出前n个学生

    if (m == -1 || y == -1 || n == -1) { printf("请输入正确的格式\n"); return; }

    int p_comp = 0; //记录参与到排名的学生的总数

    rule cur; //初始化当前规则

    cur.judge = -1;

    for (int i = 0; i < 4; i++) cur.type[i] = -1;

    for (int i = 0; i < 100; i++) { strcpy(cur.filter[i], ""); }

    if (strcmp(ref[3], "yes") == 0) {

        cur.judge = 0;

        for (int i = 0; i < 100; i++) {

            printf("请输入第 %2d 个学科的编号 (-1表示直接退出学科输入):\n", i + 1);

            gets(cur.filter[i]); //为了防止某些逆天一行输好多，我选择读一行

            if (strcmp(cur.filter[i], "-1") == 0) { printf("退出学科输入\n"); break; } //退出

            if (Check_int(cur.filter[i], strlen(cur.filter[i]), 10101, 999999) == -1) { // 编号

                printf("您输入的个学科编号不合法, 请从新输入\n");

                strcpy(cur.filter[i], "");

                i--;

            }

            else {

                printf("您输入的第 %2d 个学科编号是: %s \n", i + 1, cur.filter[i]);

                cur.judge = i + 1; // 记录需要考虑的学科总数

            }

        }

    }

    if (strcmp(ref[4], "yes") == 0) cur.type[2] = -1;

    else cur.type[2] = 1;

    if (strcmp(ref[5], "yes") == 0) cur.type[3] = -1;

    else cur.type[3] = 1;

    printf("过程稍慢, 请等待\n");

    //printf("%d %d %d\n", m, y, n);

    student* p_search = pH_student->next;

    comp rank[10000]; //用来存放所有学生， 以学号，姓名，综合成绩 三元组的形式

    while (p_search != NULL) {

        if (p_search->major != m && m != -2) { //判断是否有专业限制， 进一步判断是否符合

            p_search = p_search->next;

            continue;

        }

        if (p_search->session != y && y != -2) { //判断是否有届数限制， 进一步判断是否符合

            p_search = p_search->next;

            continue;

        }

        //printf("%s\n",p_search->id);

        strcpy(rank[p_comp].id, p_search->id);

        strcpy(rank[p_comp].name, p_search->name);

        rank[p_comp].complex_grade = 0; //初始化

        float temp1 = Calu_common(p_search, &cur), temp2 = Calu_bouns(p_search); // 算两种成绩

        if (temp1 > 0) rank[p_comp].complex_grade += temp1;

        if (temp2 > 0 && (strcmp(ref[6], "yes") == 0)) rank[p_comp].complex_grade += temp2;

        if (rank[p_comp].complex_grade > 4) rank[p_comp].complex_grade = 4;

        p_search = p_search->next;

        p_comp++;

    }

    qsort(rank, p_comp, sizeof(comp), Cmp); //还不清楚排序是从大到小还是从小到大

    if (n == -2 || n > p_comp) n = p_comp; //没有人数要求 / 总人数不够要求

    for (int i = 0; i < n; i++) {

        printf("第%3d 名 学号：%s\t姓名：%s\t加权成绩：%.2f\n", i+1, rank[i].id, rank[i].name, rank[i].complex_grade);

    }

    return;

}

void Get() {

    if (View_Level < 2 && strcmp(User, ref[0]) != 0) { printf("账户权限不足 \n"); return; }

    int tmp = Check_int(ref[1], strlen(ref[1]), 1, 5);
    
    if (tmp == -1) { printf("请输入正确的参数\n"); return; }

    student* p_find = pH_student->next;

    while (p_find != NULL) { if (strcmp(p_find->id, ref[0]) == 0) break; p_find = p_find->next; }//这个循环结束时，p_find指向查找的学生或空

    if (p_find == NULL) { printf("没有找到该学生\n");  return; }  //找不到学生，立刻返回

    if (tmp == 1) {

        read_subject(p_find);

        subject* p1 = (p_find->pH_subject)->next;

        while (p1 != NULL) {

            print_subject(p1);

            p1=p1->next;

        }

    }

    if (tmp == 2) {

        read_project(p_find);

        project* p2 = (p_find->pH_project)->next;

        while (p2 != NULL) {

            print_project(p2);

            p2 = p2->next;

        }

    }

    if (tmp == 3) {

        read_paper(p_find);

        paper * p3 = (p_find->pH_paper)->next;

        while (p3 != NULL) {

            print_paper(p3);

            p3 = p3->next;

        }

    }

    if (tmp == 4) {

        read_medal(p_find);

        medal* p4 = (p_find->pH_medal)->next;

        while (p4 != NULL) {

            print_medal(p4);

            p4 = p4->next;

        }

    }

}

void Entry() { // 录入

    if (View_Level < 2) { printf("账户权限不足 \n"); return; }

    if ((Check_int(ref[1], strlen(ref[1]), 0, 99999999) == -1 || strlen(ref[1]) != 8)) { printf("学号格式输入错误\n"); return; } // 检查学号格式（每个录入方式都有学号）

    if (strcmp(ref[0], "0") == 0) {  // 0 表示 录入学生信息

        if (strlen(ref[2]) > 27) { printf("姓名字数超出上限\n");  return; } // 检查姓名字数 000

        if (Check_space(ref[2]) == 1) { printf("姓名不能包含空格\n");  return; }

        if (!(strcmp(ref[3], "male") == 0 || strcmp(ref[3], "female") == 0 || strcmp(ref[3], "") == 0)) { printf("性别输入错误\n"); return; } // 检查性别

        int maj = Check_int(ref[4], strlen(ref[4]), 0, 99);

        if (maj == -1) { printf("专业编号输入错误\n"); return; } //检查专业编号

        int sess = Check_int(ref[5], strlen(ref[5]), 0, 99);

        if (sess == -1) { printf("学年输入错误\n"); return; } //检查学年

        if (id_search_student(ref[1]) == NULL) { // 该学生不存在

            create_student();

            strcpy(pT_student->id, ref[1]);

            strcpy(pT_student->name, ref[2]);

            if (strcmp(ref[2], "") == 0) { strcpy(pT_student->name, "null"); }

            strcpy(pT_student->sexual, ref[3]);

            if (strcmp(ref[3], "") == 0) { strcpy(pT_student->sexual, "null"); }

            pT_student->major = maj;

            pT_student->session = sess;

            printf("录入成功！\n");

        }

        else  printf("该学生已存在，若要修改信息请调用Revise\n");

        return;

    }

    if (strcmp(ref[0], "1") == 0) { // 1 表示录入某学生学科信息

        student* p;

        p = id_search_student(ref[1]);

        if (p != NULL) { // 该学生存在

            if (Check_int(ref[2], strlen(ref[2]), 10101, 999999) == -1 || Check_int(ref[2], strlen(ref[2]), 10101, 999999) == -2) { printf("学科编号输入错误\n"); return; } // 检查学科编号

            if (strlen(ref[3]) > 42) { printf("学科名称字数超出上限\n"); return; } // 检查学科名称字数 000

            if (Check_space(ref[3]) == 1) { printf("学科名称不能包含空格\n"); return; }

            float cal = Check_float(ref[4], strlen(ref[4]), 0, 4);

            if (cal == -1 || cal == -2) { printf("学科学分输入错误\n"); return; } // 检查学科学分

            float gra = Check_float(ref[5], strlen(ref[5]), 0, 100);

            if (gra == -1 || gra == -2) { printf("学科成绩输入错误\n"); return; } // 检查学科成绩

            int typ = Check_int(ref[6], strlen(ref[6]), 0, 3);

            if (typ == -1 || typ == -2) { printf("学科类型输入错误\n"); return; } // 检查学科类型

            read_subject(p);

            if (node_search_subject(p, ref[2]) == NULL) { // 学科信息不存在

                create_subject(p);

                strcpy(p->pT_subject->node, ref[2]);

                strcpy(p->pT_subject->name, ref[3]);

                if (strcmp(ref[3], "") == 0) { strcpy(p->pT_subject->name, "null"); }

                p->pT_subject->cavlue = cal;

                p->pT_subject->grade = gra;

                p->pT_subject->gpa = Get_gpa(p->pT_subject->grade);

                p->pT_subject->type = typ;

                if (typ == -2) { p->pT_subject->type = 0; }

                printf("录入成功！\n");

            }

            else printf("学科已存在，若要修改信息请调用Revise\n");

            write_subject(p);

        }

        else printf("找不到学生\n");

        return;

    }

    if (strcmp(ref[0], "2") == 0) { // 录入某学生项目信息

        student* p;

        p = id_search_student(ref[1]);

        if (p != NULL) { // 该学生存在

            if (Check_int(ref[2], strlen(ref[2]), 0, 99999999) == -1 || strlen(ref[2]) != 8) { printf("项目编号输入错误\n");  return; } // 检查项目编号

            if (strlen(ref[3]) > 42) { printf("项目名称字数超出上限\n"); return; } // 检查项目名称 000

            if (Check_space(ref[3]) == 1) { printf("项目名称不能包含空格\n"); return; }

            char member_tmp[20][30]; // 创建临时成员变量

            int num1 = Check_split(member_tmp, ref[4], ' ', 20, 30); // 成员个数

            if (num1 == -1) { printf("项目成员人数超出上限\n");  return; } // 检查成员人数

            if (num1 == -2) { printf("存在项目成员名字字数超出上限\n"); return; } // 检查成员名字字数上限

            if (strlen(ref[5]) > 27) { printf("项目导师名字字数超出上限\n"); return; } // 检查项目导师名字字数上限

            if (Check_space(ref[5]) == 1) { printf("项目导师名字不能包含空格\n"); return; }

            char time_tmp1[3][30], time_tmp2[3][30]; // 创建临时时间变量

            int tmp1 = Check_split(time_tmp1, ref[6], '.', 3, 5); // 年(1874-2300) 月 日

            if (tmp1 != 3 && strcmp(ref[6], "") != 0) { printf("时间格式错误\n");  return; }

            int y1 = Check_int(time_tmp1[0], strlen(time_tmp1[0]), 1874, 2300);

            int m1 = Check_int(time_tmp1[1], strlen(time_tmp1[1]), 1, 12);

            int d1 = Check_int(time_tmp1[2], strlen(time_tmp1[2]), 1, 31);

            if ((y1 == -1 || m1 == -1 || d1 == -1) && strcmp(ref[6], "") != 0) { printf("时间输入错误\n"); return; }

            int tmp2 = Check_split(time_tmp2, ref[7], '.', 3, 5); // 年(1874-2300) 月 日

            if (tmp2 != 3 && strcmp(ref[7], "") != 0) { printf("时间格式错误\n");  return; }

            int y2 = Check_int(time_tmp2[0], strlen(time_tmp2[0]), 1874, 2300);

            int m2 = Check_int(time_tmp2[1], strlen(time_tmp2[1]), 1, 12);

            int d2 = Check_int(time_tmp2[2], strlen(time_tmp2[2]), 1, 31);

            if ((y2 == -1 || m2 == -1 || d2 == -1) && strcmp(ref[7], "") != 0) { printf("时间输入错误\n"); return; }

            if (Check_float(ref[8], strlen(ref[8]), 0, 0.4) == -1 || Check_float(ref[8], strlen(ref[8]), 0, 0.4) == -2) { printf("分数加成输入错误\n");  return; }

            read_project(p);

            if (node_search_project(p, ref[2]) == NULL) { // 项目信息不存在

                create_project(p);

                strcpy(p->pT_project->node, ref[2]);

                strcpy(p->pT_project->name, ref[3]);

                if (strcmp(ref[3], "") == 0) { strcpy(p->pT_project->name, "null"); }

                for (int i = 0; i < num1; i++) { strcpy(p->pT_project->member[i], member_tmp[i]); }

                strcpy(p->pT_project->teacher, ref[5]);

                if (strcmp(ref[5], "") == 0) { strcpy(p->pT_project->teacher, "null"); }

                input_time(&(p->pT_project->start), y1, m1, d1);

                input_time(&(p->pT_project->finish), y2, m2, d2);

                p->pT_project->level = Check_float(ref[8], strlen(ref[8]), 0, 0.4);

                printf("录入成功！\n");

            }

            else printf("该项目已存在，若要修改信息请调用Revise\n");

            write_project(p);

        }

        else printf("学生不存在\n");

        return;

    }

    if (strcmp(ref[0], "3") == 0) { // 录入某学生论文信息

        student* p;

        p = id_search_student(ref[1]);

        if (p != NULL) { // 该学生存在

            if (Check_int(ref[2], strlen(ref[2]), 0, 99999999) == -1 || strlen(ref[2]) != 8) { printf("论文编号输入错误\n");  return; } // 检查论文编号

            if (strlen(ref[3]) > 42) { printf("论文名称字数超出上限\n"); return; } // 检查论文名称 000

            if (Check_space(ref[3]) == 1) { printf("论文名称不能包含空格\n"); return; }

            char member_tmp[20][30]; // 创建临时成员变量

            int num1 = Check_split(member_tmp, ref[4], ' ', 20, 30); // 成员个数

            if (num1 == -1) { printf("论文成员人数超出上限\n");  return; } // 检查成员人数

            if (num1 == -2) { printf("存在论文成员名字字数超出上限\n"); return; } // 检查成员名字字数上限

            char time_tmp[3][30]; // 创建临时时间变量

            int tmp = Check_split(time_tmp, ref[5], '.', 3, 5); // 年(1874-2300) 月 日

            if (tmp != 3 && strcmp(ref[5], "") != 0) { printf("时间格式错误\n");  return; }

            int y = Check_int(time_tmp[0], strlen(time_tmp[0]), 1874, 2300);

            int m = Check_int(time_tmp[1], strlen(time_tmp[1]), 1, 12);

            int d = Check_int(time_tmp[2], strlen(time_tmp[2]), 1, 31);

            if ((y == -1 || m == -1 || d == -1) && strcmp(ref[5], "") != 0) { printf("时间输入错误\n"); return; }

            if (Check_float(ref[6], strlen(ref[6]), 0, 0.4) == -1 || Check_float(ref[6], strlen(ref[6]), 0, 0.4) == -2) { printf("分数加成输入错误\n");  return; }

            read_paper(p);

            if (node_search_paper(p, ref[2]) == NULL) { // 论文信息不存在

                create_paper(p);

                strcpy(p->pT_paper->node, ref[2]);

                strcpy(p->pT_paper->name, ref[3]);

                if (strcmp(ref[3], "") == 0) { strcpy(p->pT_paper->name, "null"); }

                for (int i = 0; i < num1; i++) { strcpy(p->pT_paper->member[i], member_tmp[i]); }

                input_time(&(p->pT_paper->date), y, m, d);

                p->pT_paper->level = Check_float(ref[6], strlen(ref[6]), 0, 0.4);

                printf("录入成功！\n");

            }

            else printf("该论文已存在，若要修改信息请调用Revise\n");

            write_paper(p);

        }

        else printf("学生不存在\n");

        return;

    }

    if (strcmp(ref[0], "4") == 0) { // 录入某学生竞赛信息

        student* p;

        p = id_search_student(ref[1]);

        if (p != NULL) { // 该学生存在

            if (Check_int(ref[2], strlen(ref[2]), 0, 99999999) == -1 || strlen(ref[2]) != 8) { printf("竞赛编号输入错误\n");  return; } // 检查竞赛编号

            if (strlen(ref[3]) > 42) { printf("竞赛名称字数超出上限\n"); return; } // 检查竞赛名称 000

            if (Check_space(ref[3]) == 1) { printf("竞赛名称不能包含空格\n"); return; }

            char member_tmp[20][30]; // 创建临时成员变量

            int num1 = Check_split(member_tmp, ref[4], ' ', 20, 30); // 成员个数

            if (num1 == -1) { printf("竞赛成员人数超出上限\n");  return; } // 检查成员人数

            if (num1 == -2) { printf("存在竞赛成员名字字数超出上限\n"); return; } // 检查成员名字字数上限

            char time_tmp[3][30]; // 创建临时时间变量

            if (strlen(ref[5]) > 42) { printf("组织者名称字数超出上限\n"); return; } // 检查组织者名称 000

            if (Check_space(ref[5]) == 1) { printf("组织者名称不能包含空格\n"); return; }

            int tmp = Check_split(time_tmp, ref[6], '.', 3, 5); // 年(1874-2300) 月 日

            if (tmp != 3 && strcmp(ref[6], "") != 0) { printf("时间格式错误\n");  return; }

            int y = Check_int(time_tmp[0], strlen(time_tmp[0]), 1874, 2300);

            int m = Check_int(time_tmp[1], strlen(time_tmp[1]), 1, 12);

            int d = Check_int(time_tmp[2], strlen(time_tmp[2]), 1, 31);

            if ((y == -1 || m == -1 || d == -1) && strcmp(ref[6], "") != 0) { printf("时间输入错误\n"); return; }

            if (Check_float(ref[7], strlen(ref[7]), 0, 0.4) == -1 || Check_float(ref[7], strlen(ref[7]), 0, 0.4) == -2) { printf("分数加成输入错误\n");  return; }

            read_medal(p);

            if (node_search_medal(p, ref[2]) == NULL) { // 竞赛信息不存在

                create_medal(p);

                strcpy(p->pT_medal->node, ref[2]);

                strcpy(p->pT_medal->name, ref[3]);

                if (strcmp(ref[3], "") == 0) { strcpy(p->pT_medal->name, "null"); }

                for (int i = 0; i < num1; i++) { strcpy(p->pT_medal->member[i], member_tmp[i]); }

                strcpy(p->pT_medal->organizer, ref[5]);

                if (strcmp(ref[5], "") == 0) { strcpy(p->pT_medal->organizer, "null"); }

                input_time(&(p->pT_medal->date), y, m, d);

                p->pT_medal->level = Check_float(ref[7], strlen(ref[7]), 0, 0.4);

                printf("录入成功！\n");

            }

            else printf("该竞赛信息已存在，若要修改信息请调用Revise\n");

            write_medal(p);

        }

        else printf("该学生不存在\n");

        return;

    }

    printf("参数格式错误\n");

}


void Revise() { // 修改  

    if (View_Level < 2) { printf("账户权限不足 \n"); return; }

    if ((Check_int(ref[1], strlen(ref[1]), 0, 99999999) == -1 || strlen(ref[1]) != 8)) { printf("学号格式输入错误\n"); return; } // 检查学号格式（每个录入方式都有学号）

    if (strcmp(ref[0], "0") == 0) { // 修改学生信息

        if (strlen(ref[2]) > 27) { printf("姓名字数超出上限\n");  return; } // 检查姓名字数

        if (Check_space(ref[2]) == 1) { printf("姓名不能包含空格\n");  return; }

        if (!(strcmp(ref[3], "male") == 0 || strcmp(ref[3], "female") == 0 || strcmp(ref[3], "") == 0)) { printf("性别输入错误\n"); return; } // 检查性别

        int maj = Check_int(ref[4], strlen(ref[4]), 0, 99);

        if (maj == -1) { printf("专业编号输入错误\n"); return; } //检查专业编号

        int sess = Check_int(ref[5], strlen(ref[5]), 0, 99);

        if (sess == -1) { printf("学年输入错误\n"); return; } //检查学年

        student* p = id_search_student(ref[1]);

        if (p != NULL) { // 该学生存在

            if (strcmp(ref[1], "") != 0) strcpy(p->id, ref[1]);

            if (strcmp(ref[2], "") != 0) strcpy(p->name, ref[2]);

            if (strcmp(ref[3], "") != 0) strcpy(p->sexual, ref[3]);

            if (strcmp(ref[4], "") != 0) p->major = Check_int(ref[4], strlen(ref[4]), 0, 99);

            if (strcmp(ref[5], "") != 0) p->session = Check_int(ref[5], strlen(ref[5]), 0, 99);

            printf("修改成功！\n");

        }

        else printf("该学生不存在\n");

        return;

    }

    if (strcmp(ref[0], "1") == 0) { // 修改学科信息

        student* p = id_search_student(ref[1]);

        if (p != NULL) { // 该学生存在

            if (Check_int(ref[2], strlen(ref[2]), 10101, 999999) == -1 && strcmp(ref[2], "") != 0) { printf("学科编号输入错误\n"); return; } // 检查学科编号

            if (strlen(ref[3]) > 42) { printf("学科名称字数超出上限\n"); return; } // 检查学科名称字数

            if (Check_space(ref[3]) == 1) { printf("名称不能包含空格\n");  return; }

            int cal = Check_float(ref[4], strlen(ref[4]), 0, 4);

            if (cal == -1) { printf("学科学分输入错误\n"); return; } // 检查学科学分

            int gra = Check_float(ref[5], strlen(ref[5]), 0, 100);

            if (gra == -1) { printf("学科成绩输入错误\n"); return; } // 检查学科成绩

            int typ = Check_int(ref[6], strlen(ref[6]), 0, 3);

            if (typ == -1) { printf("学科类型输入错误\n"); return; } // 检查学科类型

            read_subject(p);

            subject* q = node_search_subject(p, ref[2]);

            if (q != NULL) { // 学科信息存在

                if (strcmp(ref[3], "") != 0) strcpy(q->name, ref[3]);

                if (strcmp(ref[4], "") != 0) q->cavlue = cal;

                if (strcmp(ref[5], "") != 0) {

                    q->grade = gra;

                    q->gpa = Get_gpa(q->grade);

                }

                if (strcmp(ref[6], "") != 0) q->type = typ;

                printf("修改成功！\n");

            }

            else printf("学科信息不存在\n");

            write_subject(p);

        }

        else printf("学生不存在\n");

        return;

    }

    if (strcmp(ref[0], "2") == 0) { // 修改项目信息

        student* p = id_search_student(ref[1]);

        if (p != NULL) { // 该学生存在

            if (Check_int(ref[2], strlen(ref[2]), 0, 99999999) == -1 || strlen(ref[2]) != 8) { printf("项目编号输入错误\n");  return; } // 检查项目编号

            if (strlen(ref[3]) > 42) { printf("项目名称字数超出上限\n"); return; } // 检查项目名称

            if (Check_space(ref[3]) == 1) { printf("名称不能包含空格\n");  return; }

            char member_tmp[20][30]; // 创建临时成员变量

            int num1 = Check_split(member_tmp, ref[4], ' ', 20, 30); // 成员个数

            if (num1 == -1) { printf("项目成员人数超出上限\n");  return; } // 检查成员人数

            if (num1 == -2) { printf("存在项目成员名字字数超出上限\n"); return; } // 检查成员名字字数上限

            if (strlen(ref[5]) > 27) { printf("项目导师名字字数超出上限\n"); return; } // 检查项目导师名字字数上限

            char time_tmp1[3][30], time_tmp2[3][30]; // 创建临时时间变量

            int tmp1 = Check_split(time_tmp1, ref[6], '.', 3, 5); // 年(1874-2300) 月 日

            if (tmp1 != 3 && strcmp(ref[6], "") != 0) { printf("时间格式错误\n");  return; }

            int y1 = Check_int(time_tmp1[0], strlen(time_tmp1[0]), 1874, 2300);

            int m1 = Check_int(time_tmp1[1], strlen(time_tmp1[1]), 1, 12);

            int d1 = Check_int(time_tmp1[2], strlen(time_tmp1[2]), 1, 31);

            if ((y1 == -1 || m1 == -1 || d1 == -1) && strcmp(ref[6], "") != 0) { printf("时间输入错误\n"); return; }

            int tmp2 = Check_split(time_tmp2, ref[7], '.', 3, 5); // 年(1874-2300) 月 日

            if (tmp2 != 3 && strcmp(ref[7], "") != 0) { printf("时间格式错误\n");  return; }

            int y2 = Check_int(time_tmp2[0], strlen(time_tmp2[0]), 1874, 2300);

            int m2 = Check_int(time_tmp2[1], strlen(time_tmp2[1]), 1, 12);

            int d2 = Check_int(time_tmp2[2], strlen(time_tmp2[2]), 1, 31);

            if ((y2 == -1 || m2 == -1 || d2 == -1) && strcmp(ref[7], "") != 0) { printf("时间输入错误\n"); return; }

            if (Check_float(ref[8], strlen(ref[8]), 0, 0.4) == -1) { printf("分数加成输入错误\n");  return; }

            read_project(p);

            project* q = node_search_project(p, ref[2]);

            if (q != NULL) { // 项目信息存在

                if (strcmp(ref[3], "") != 0) strcpy(q->name, ref[3]);

                if (num1 != 0) for (int i = 0; i < 20; i++) { strcpy(q->member[i], "null"); }

                for (int i = 0; i < num1; i++) { strcpy(q->member[i], member_tmp[i]); }

                if (strcmp(ref[5], "") != 0) strcpy(q->teacher, ref[5]);

                if (strcmp(ref[6], "") != 0) { input_time(&(q->start), y1, m1, d1); }

                if (strcmp(ref[7], "") != 0) { input_time(&(q->finish), y2, m2, d2); }

                if (strcmp(ref[8], "") != 0) q->level = Check_float(ref[8], strlen(ref[8]), 0, 0.4);

                printf("修改成功！\n");

            }

            else printf("项目信息不存在\n");

            write_project(p);

        }

        else printf("学生不存在\n");

        return;

    }

    if (strcmp(ref[0], "3") == 0) { // 修改论文信息

        student* p = id_search_student(ref[1]);

        if (p != NULL) { // 该学生存在

            if (Check_int(ref[2], strlen(ref[2]), 0, 99999999) == -1 || strlen(ref[2]) != 8) { printf("论文编号输入错误\n");  return; } // 检查论文编号

            if (strlen(ref[3]) > 42) { printf("论文名称字数超出上限\n"); return; } // 检查论文名称

            if (Check_space(ref[3]) == 1) { printf("名称不能包含空格\n");  return; }

            char member_tmp[20][30]; // 创建临时成员变量

            int num1 = Check_split(member_tmp, ref[4], ' ', 20, 30); // 成员个数

            if (num1 == -1) { printf("论文成员人数超出上限\n");  return; } // 检查成员人数

            if (num1 == -2) { printf("存在论文成员名字字数超出上限\n"); return; } // 检查成员名字字数上限

            char time_tmp[3][30]; // 创建临时时间变量

            int tmp = Check_split(time_tmp, ref[5], '.', 3, 5); // 年(1874-2300) 月 日

            if (tmp != 3 && strcmp(ref[5], "") != 0) { printf("时间格式错误\n");  return; }

            int y = Check_int(time_tmp[0], strlen(time_tmp[0]), 1874, 2300);

            int m = Check_int(time_tmp[1], strlen(time_tmp[1]), 1, 12);

            int d = Check_int(time_tmp[2], strlen(time_tmp[2]), 1, 31);

            if ((y == -1 || m == -1 || d == -1) && strcmp(ref[5], "") != 0) { printf("时间输入错误\n"); return; }

            if (Check_float(ref[6], strlen(ref[6]), 0, 0.4) == -1) { printf("分数加成输入错误\n");  return; }

            read_paper(p);

            paper* q = node_search_paper(p, ref[2]);

            if (q != NULL) { // 论文信息存在

                if (strcmp(ref[3], "") != 0) strcpy(q->name, ref[3]);

                if (num1 != 0) for (int i = 0; i < 20; i++) { strcpy(q->member[i], "null"); }

                for (int i = 0; i < num1; i++) { strcpy(q->member[i], member_tmp[i]); }

                input_time(&(q->date), y, m, d);

                if (strcmp(ref[6], "") != 0) q->level = Check_float(ref[6], strlen(ref[6]), 0, 0.4);

                printf("修改成功！\n");

            }

            else printf("论文信息不存在\n");

            write_paper(p);

        }

        else printf("学生不存在\n");

        return;

    }

    if (strcmp(ref[0], "4") == 0) { // 修改竞赛信息

        student* p = id_search_student(ref[1]);

        if (p != NULL) { // 该学生存在

            if (Check_int(ref[2], strlen(ref[2]), 0, 99999999) == -1 || strlen(ref[2]) != 8) { printf("竞赛编号输入错误\n");  return; } // 检查竞赛编号

            if (strlen(ref[3]) > 42) { printf("竞赛名称字数超出上限\n"); return; } // 检查竞赛名称

            if (Check_space(ref[3]) == 1) { printf("名称不能包含空格\n");  return; }

            char member_tmp[20][30]; // 创建临时成员变量

            int num1 = Check_split(member_tmp, ref[4], ' ', 20, 30); // 成员个数

            if (num1 == -1) { printf("竞赛成员人数超出上限\n");  return; } // 检查成员人数

            if (num1 == -2) { printf("存在竞赛成员名字字数超出上限\n"); return; } // 检查成员名字字数上限

            char time_tmp[3][30]; // 创建临时时间变量

            if (strlen(ref[5]) > 42) { printf("组织者名称字数超出上限\n"); return; } // 检查组织者名称

            if (Check_space(ref[5]) == 1) { printf("名称不能包含空格\n");  return; }

            int tmp = Check_split(time_tmp, ref[6], '.', 3, 5); // 年(1874-2300) 月 日

            if (tmp != 3 && strcmp(ref[6], "") != 0) { printf("时间格式错误\n");  return; }

            int y = Check_int(time_tmp[0], strlen(time_tmp[0]), 1874, 2300);

            int m = Check_int(time_tmp[1], strlen(time_tmp[1]), 1, 12);

            int d = Check_int(time_tmp[2], strlen(time_tmp[2]), 1, 31);

            if ((y == -1 || m == -1 || d == -1) && strcmp(ref[6], "") != 0) { printf("时间输入错误\n"); return; }

            if (Check_float(ref[7], strlen(ref[7]), 0, 0.4) == -1) { printf("分数加成输入错误\n");  return; }

            read_medal(p);

            medal* q = node_search_medal(p, ref[2]);

            if (q != NULL) { // 竞赛信息存在

                if (strcmp(ref[3], "") != 0) strcpy(q->name, ref[3]);

                if (num1 != 0) for (int i = 0; i < 20; i++) { strcpy(q->member[i],"null"); }

                for (int i = 0; i < num1; i++) { strcpy(q->member[i], member_tmp[i]); }

                if (strcmp(ref[5], "") != 0) strcpy(q->organizer, ref[5]);

                input_time(&(q->date), y, m, d);

                if (strcmp(ref[7], "") != 0) q->level = Check_float(ref[7], strlen(ref[6]), 0, 0.4);

                printf("修改成功！\n");

            }

            else printf("竞赛信息不存在\n");

            write_medal(p);

        }

        else printf("学生不存在\n");

        return;

    }

    printf("参数1 格式不正确\n");

}